/*

Mini2RAG.C (C) Copyright Bill Buckels 2008.
All rights reserved.

Written by   : Bill Buckels
Email        : bbuckels@mts.net

Date Written : May 2008

Environment  : Apple33 Manx Aztec C65 Version 3.2b
Windows XP Cross-development environment for DOS33

I have made absolutely no attempt to make this program
compatible with any C compiler outside the Apple33
environment stated above.

Purpose      : Legacy Graphics Converter

This program converts Apple IIe format Beagle Bros. and
"Old PrintShop" and "New PrintShop" Minipix to Apple II
native mode raster image fragments used by the Apple33
environment in Aztec-C programs.

This format which I have dubbed the .RAG Image Format was
developed by me around 1990. It is a variable size
uncompressed format with a 2 byte header which provides
the width of the image in bytes followed by the length in
rasters and is designed for fast loading on the Apple II
without the expanding of bytes that is inherent in using
image fragments like Minipix which do not store their
rasters in Apple II native mode.

It also loads and resaves converted RAG files if in the
Minipix size.

This utility will also invert the video in the loaded
Minipic or RAG before saving.

The source code for this utility will also serve as
an example minipix and RAG loader.


Licence Agreement
-----------------

All my work is copyrighted and belongs to me. This
program is not derived from anything by anyone and is my
own work in its entirety.

I herewith grant you a non-exclusive and conditional
licence to use this source code and the output files it
produces for whatever use you deem fit, provided you do
not take credit for my work, and that you leave my
copyright notices intact in all of it.

If you augment or otherwise use my work you must always
also include your own personal copyright notice but it
may never be a GNU public licence or anything else that
resembles fascism or totalitarianism and world-domination
or a commercial or educational licence either. You can
use my stuff commercially or for GNU with my conditions
intact if they let you (they should since copyright is
for authors and the public and I belong to both groups)
but you must never copyright my work with any company
copyright whatsoever; just your own personal copyright
like mine and leave mine in place. That is the way
copyright is intended to work and that is the way that it
will work with my stuff unless I selectively decide
otherwise.

In addition you must agree that I am not liable in any
way shape or form for any damage from the use of any of
this in any way whatsoever.

If you do not agree with all of the aforementioned
conditions of use or if your use is not Fair then remove
all of this from your computer now.

Bill Buckels
bbuckels@mts.net
May 2008

*/

#include <console.h>
#include <stdio.h>
#include <fcntl.h>
#include <dos33.h>
#include <sgtty.h>
#include <device.h>

/*

The Apple ][ Minipix Format

When The Print Shop first appeared on The Apple ][, the
only type of graphics it used were small 4 sector DOS3.3
files, called minipix. Because the range of them built
into The Print Shop® was limited, people drew their own,
using the print Shop Graphic Editor, and soon these
little 88x52 pictures were everywhere. There were disks
and disks, just packed with them. The storage format was
quite simple, basically just a bit mapped image, with
every 11 bytes of the file mapping to one line of 88 dots
on the screen. An extra 4 filler bytes were tacked on the
end of each mini-graphic file. Each file held only 1
mini-graphic. 52 lines x 8 bytes + 4 = 576 bytes. Now
when "The New Print Shop" came along, you could convert
these little graphics to the new format. It turns out
that all that was done to each graphic to convert it, was
a small header was placed at the start, and the 4 filler
bytes were dropped from the end, and so 576 byte graphics
became 605 byte "NPS" compatible graphics.

*/

int getch();
#define clearscreen() fbox(0,0,39,191,0)

/* as noted above, 2 Minipix formats exist.
this program will convert either */
#define NEW_CHUNK 605
#define OLD_CHUNK 576
#define NEW_HEADER 33
#define OLD_HEADER 0
#define PSHOP_CHUNK 572

/* 2 byte header + 13 byte width x 52 rasters */
#define RAG_SIZE 678

char MiniPic[RAG_SIZE];
char RagBuffer[RAG_SIZE];

int minihead = OLD_HEADER;

int palette = 0x80;
int flength = OLD_CHUNK;
int faddress = 0x5800;

main()
{
   int c,R,A,G,Z,idx,ragmode,oldpalette;
   char picname[66];

   setcrtmode(2);
   if (getch() != 27) {

   		blue();

        setcrtmode(0);
        scr_clear();
        printf("Mini2Rag(C) Bill Buckels 2008\n");
        printf("All Rights Reserved.\n");
        printf("Enter \"?\" for CATALOG\n");
        printf("Enter a Blank to Exit to DOS33\n");
   		for (;;) {

   			printf("Enter Minipic or RAG: ");
   			gets(picname); /* get the filename */
   			if (picname[0] == 0)break;
   			if (picname[0] == '?') {
				scr_apple();
				catalog();
				continue;
			}

   			printf("Please Wait! Now loading...\n");

			ragmode = 0;
			for (idx = 0; picname[idx] != 0; idx++) {
			    if (picname[idx] != '.')continue;
			    R = picname[idx + 1];
			    A = picname[idx + 2];
			    G = picname[idx + 3];
			    if (R == 'R' && A == 'A' && G == 'G') {
					ragmode = 1;
					break;
				}
			}

            c = MiniRead(picname);
            if (c!=0) {
				bellerr();
                if (c == -1) printf("! Can't open %s\n",picname);
                else printf("! Filelength = %d\n%s not a Minipic\n",flength,picname);
				continue;
			}

            setcrtmode(2);
            clear_bottom();
            mscreen(); /* mixed text and graphics */
            print_bottom("Please Wait some more...",1,0);
	        print_bottom(picname,3,0);
            if (ragmode == 0)mini2rag();
            putimage(&RagBuffer[2],13,52,13,52,0);
            clear_bottom();
            print_bottom("'S' to Save       'R' to Reverse",1,0);
            print_bottom("'O' Orange-Blue   'G' Green-Violet",2,0);
            print_bottom("Press Any Other Key to Continue...",3,0);
            /* menu loop */
            for(;;) {
				c = toupper(getch());
				/* put other menu options here */
				if (c == 'R') {
					revrag();
            		putimage(&RagBuffer[2],13,52,13,52,0);
            		continue;
				}
				if (c == 'G' || c == 'O') {
				     oldpalette = palette;
				     palette = 0x80;
				     if (c == 'G')palette = 0;
				     if (oldpalette != palette) {
						 palset();
						 putimage(&RagBuffer[2],13,52,13,52,0);
					 }
				     continue;
				}
				break;
			}

            if (c == 'S') {
				/*
				    If the loaded graphic is a MiniPic
				    add the .RAG filename extension.
					ProDOS allowed only fifteen characters in a
					filename compared to Apple DOS's thirty.
					We need to truncate the basename at 12 for
					our extension.
				*/
				if (ragmode == 0) {
					picname[11] = 0;
					strcat(picname,".RAG");
				}
				clear_bottom();
				print_bottom("Please Wait!. Now Saving...",1,0);
			    print_bottom(picname,3,0);

				c = ragsave(picname);
			}
			else c = 27;
			fscreen(); /* graphics only */
			clear_bottom();
			setcrtmode(0);
			scr_clear();
			if (c == 0)printf("%s saved\n",picname);
			else if (c == -1)printf("Can't open %s\n",picname);
			else if (c == -2)printf("Can't save %s\n",picname);
		}
   }
   else setcrtmode(0);
/*
   exit(0);
*/
scr_apple();
reboot();
}

palset()
{
	/* palette */
	int offset;
	char c;
	for (offset = 2; offset < RAG_SIZE; offset++) {
		c = (RagBuffer[offset] & 0x7f); /* strip palette bit */
		RagBuffer[offset] = (c | palette);

	}
	return 0;
}

revrag()
{
	/* inverse video */
	int offset;
	char c;
	for (offset = 2; offset < RAG_SIZE; offset++) {
		c = (RagBuffer[offset] ^ 0x7f);
		RagBuffer[offset] = c;

	}
	return 0;
}

/* read a minipic in 2 formats */
MiniRead(name)
char *name;
{
   int fh, c;

   /* read works differently in DOS33 than
      in ProDOS and the first 4 bytes
      are the BSaved Address and File Length
      for all binary files.

      In fact, this is how we get the file length
      since seek is not reliable in DOS33. */

   faddress = 0;
   flength = 0;
   fh = open(name,O_RDONLY,0x04);
   if (fh == -1)return -1;
   /* we can't go by the load address */
   /* we don't really know what that could be */
   /* these were created by various processes */
   c = read(fh,&faddress,2);
   if (c == 2)c = read(fh,&flength, 2);
   else c = 0;
   if (c == 2)c = read(fh,&MiniPic[0],flength);
   else c = 0;
   close(fh);

   flength = c;

   switch(flength)
   {
	   case NEW_CHUNK:
	   	  minihead = NEW_HEADER;
	   	  palette = 0x80; /* orange, blue */
	   	  c = 0;
	   	  break;
	   case OLD_CHUNK:
	      palette = 0x80; /* orange, blue */
	      minihead = OLD_HEADER;
	      c = 0;
	      break;
	   case RAG_SIZE:
	      minihead = 0;
	      c = -2;
	      if (MiniPic[0] == 13 && MiniPic[1] == 52) {
			  for (c = 0; c < RAG_SIZE; c++)RagBuffer[c] = MiniPic[c];
			  palette = 0; /* green, violet */
			  c = RagBuffer[2];
			  if (c & 0x80)palette = 0x80; /* orange, blue */
			  c = 0;
		  }
		  break;
	   default:
	      c = -2;
	      break;
   }
   return (c);

}


/* expand a minipic into a RAG formatted buffer */
/* the minipic width is 88 pixels.
   since rasters are 7 pixels per byte this means
   that 3 pixels will remain unset in the minipic
   for each raster when saving to a byte oriented
   image fragment in the .RAG format which will
   have 13 bytes (91 pixels) per native mode scanline.

 */
int msk[]={0x80,0x40,0x20,0x10,0x8,0x4,0x2,0x1};
mini2rag()
{
	int c,x,x1,y,y1,offset,byteoff,bitoff,idx;

    if (minihead != OLD_HEADER && minihead != NEW_HEADER)return 0;

    /* create the RAG header and set the RAG background to black */
    /* use the orange and blue palette */
    RagBuffer[0] = 13; /* bytes */
    RagBuffer[1] = 52; /* height */
    for (offset = 2; offset < RAG_SIZE; offset++)RagBuffer[offset] = palette;

	offset = minihead;
	/* yterm */
	for (y = 0; y < 52; y++) {
		/* get the start of the raster in the RAG buffer */
		y1 = (y * 13) + 2;
	    /* xterm */
	    x = 0;
	    for (x1 = 0; x1 < 11; x1++) {
	        /* get the next byte in the MiniPic */
	        c = MiniPic[offset];
			offset++;
            /* set each pixel in the RAG buffer
               by translating from 8 bit monochrome graphics
               to Apple II 7 bit graphics
               this amounts to reducing from 8 pixels to 7 pixels
               per byte */
			for (idx = 0; idx < 8; idx++) {
				if ( c&msk[idx]) {
					byteoff = y1 + (x/7);
					bitoff = x%7;
					RagBuffer[byteoff] |= (1 << bitoff);
				}
				x++;

			}
		}
	}
    return 0;

}

/* save the minipic in rag format */
/*

When open is used to creat a file under DOS 3.3, param3 is the file's type:

    Param3,hex    File type

    00            Text
    01            Integer basic
    02            Applesoft basic
    04            Binary
    08            Relocatable
    10            S-type file
    20            A-type file
    40            B-type file

*/
ragsave(savex)
char *savex;
{
    int fh, c=-1;

    faddress = 0x2000; /* setting screen 1 as load address */
    flength = RAG_SIZE;

    if((fh=open(savex, O_WRONLY|O_TRUNC|O_CREAT,0x04)) != -1)
        {
	    c = write(fh,&faddress,2);
	    if (c==2)c = write(fh,&flength,2);
        if (c==2)c = write(fh,RagBuffer,RAG_SIZE);
        close(fh);
        if (c!= RAG_SIZE) c = -2;
        else c = 0;
    }
    return c;
}


